import 'dart:async';
import 'dart:io';

import 'package:device_info/device_info.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:package_info/package_info.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:qgchat/common/class/db/db.dart';
import 'package:qgchat/common/class/websocket/index.dart';
import 'package:qgchat/common/global/global.dart';
import 'package:qgchat/http/apis/user.dart';
import 'package:qgchat/http/models/DeviceInfoModel.dart';
import 'package:qgchat/http/models/IPModel.dart';
import 'package:qgchat/http/models/userInfoModel.dart';

/// 全局方法
class CommonAction {
  /// 判断主播状态
  static AnchorStatus checkAnchorStatus(int disturb, online) {
    if (disturb != 1) {
      if (online.runtimeType == String) {
        online = int.parse(online);
      }
      switch (online) {
        case 0:
          return AnchorStatus(1, '离线', false, col('9f9f9f'));
        case 1:
          return AnchorStatus(2, '在线', true, col('35f0a6'));
        case 2:
          return AnchorStatus(3, '在聊', true, col('5640c6'));
        default:
          return AnchorStatus(0, '未知', false, col('000000'));
      }
    } else {
      return AnchorStatus(4, '勿扰', true, col('ff4a12'));
    }
  }

  /// 初始化app数据(场景：登录、后台重新返回前台)
  static Future initAppData(BuildContext context, String token) async {
    if (token == null) {
      return false;
    }

    UserInfoModel userInfo;
    try {
      userInfo = await state(context, "user").initApp(token);
    } catch (e) {
      print(e);
    }

    Global.db = Db(userInfo);
    await Global.db.openDb();
    await Global.db.queryMyAll(ctx: context);

    if (Global.ws != null) {
      Global.ws?.dispose();
    }
    Global.ws = WebSocket(userInfo);
    // 登录日志
    CommonAction.deviceDetailInfo().then((device) async {
      UserApis.loginLog(device.toJson());
    });

    return userInfo;
  }

  /// 清除app数据(场景：退出登录)
  static void clearAppData(context) {
    state(context, "socket").disposeAll();
    state(context, "user").disposeAll();
    Global.db?.close();
    Global.ws?.dispose();
  }

  /// 节流
  /// ```
  /// callback 回调函数
  /// duration 节流间隔 默认500毫秒
  /// ```
  static Function([dynamic]) throttle(
    Function(dynamic) callback, {
    Duration duration = const Duration(milliseconds: 500),
  }) {
    bool canRun = true;
    return ([agrs]) {
      if (canRun) {
        callback(agrs);
        Timer(duration, () => canRun = true);
        canRun = false;
      }
    };
  }

  /// 手动防抖
  /// ```
  /// callback(reset, agrs) 回调函数
  /// reset 重置状态的方法
  /// agrs 可能传过来的参数
  /// ```
  static Function([dynamic]) debounce(Function(Function(), dynamic) callback) {
    bool canRun = true;

    // 恢复可执行状态
    reset() => canRun = true;

    return ([agrs]) {
      if (canRun) {
        canRun = false;
        callback(reset, agrs);
      }
    };
  }

  /// 拉白
  static Future outBlack(int id) async {
    Map result = await UserApis.black(id, type: 0);
    if (result['status'] == 1) {
      showToast("解除拉黑成功");
    }
    return result;
  }

  /// 拉黑
  static Future toBlack(int id) async {
    Map result = await UserApis.black(id);
    if (result['status'] == 1) {
      showToast("拉黑成功");
    }
    return result;
  }

  /// 获取设备信息
  static Future<String> deviceInfo() async {
    DeviceInfoPlugin phoneInfo = DeviceInfoPlugin();
    if (Platform.isAndroid) {
      AndroidDeviceInfo androidInfo = await phoneInfo.androidInfo;
      return androidInfo.androidId;
    } else if (Platform.isIOS) {
      IosDeviceInfo iosInfo = await phoneInfo.iosInfo;
      return iosInfo.identifierForVendor;
    } else {
      return null;
    }
  }

  /// 获取设备信息
  static Future<DeviceInfoModel> deviceDetailInfo() async {
    PackageInfo package = await PackageInfo.fromPlatform();
    await PermissionHandler().requestPermissions([PermissionGroup.location]);
    // Location location = await AmapLocation.instance.fetchLocation();
    DeviceInfoPlugin phoneInfo = DeviceInfoPlugin();
    IPModel ipModel = await checkIP();
    DeviceInfoModel data;

    String channel;
    switch (Config.apkChannel) {
      case ApkChannel.douyin:
        channel = "douyin";
        break;
      case ApkChannel.baidu:
        channel = "baidu";
        break;
      default:
        channel = "normal";
    }

    if (Platform.isAndroid) {
      AndroidDeviceInfo androidInfo = await phoneInfo.androidInfo;
      data = DeviceInfoModel.fromJson({
        "ip": ipModel?.ip,
        "app_verison": "${package.version}+${package.buildNumber}",
        "lat": ipModel?.lat,
        "lon": ipModel?.lon,
        // "country": location.country,
        // "province": location.province,
        // "city": location.city,
        // "district": location.district,
        // "address": location.address,
        "deviceid": androidInfo.androidId,
        "system": "android",
        "version": androidInfo.version.release,
        "brand": androidInfo.manufacturer,
        "model": androidInfo.model,
        "channel": channel,
      });
    } else if (Platform.isIOS) {
      // https://www.theiphonewiki.com/wiki/Models
      IosDeviceInfo iosInfo = await phoneInfo.iosInfo;
      data = DeviceInfoModel.fromJson({
        "ip": ipModel?.ip,
        "app_verison": "${package.version}+${package.buildNumber}",
        "lat": ipModel?.lat,
        "lon": ipModel?.lon,
        // "country": location.country,
        // "province": location.province,
        // "city": location.city,
        // "district": location.district,
        // "address": location.address,
        "deviceid": iosInfo.identifierForVendor,
        "system": "ios",
        "version": iosInfo.systemVersion,
        "brand": iosInfo.model,
        "model": iosInfo.utsname.machine,
        "channel": channel,
      });
    }

    return data;
  }

  /// 查询ip 地址 经纬度
  static Future<IPModel> checkIP({String query = ''}) async {
    try {
      Response res = await Dio().get("http://ip-api.com/json/$query");
      return IPModel.fromJson(res.data);
    } catch (e) {
      print('----- ip获取失败 -----');
      return null;
    }
  }
}

/// map转model
class AnchorStatus {
  AnchorStatus(this.status, this.text, this.isOnline, this.color);

  final int status;
  final String text;
  final bool isOnline;
  final Color color;
}
